package com.wgzx.modbus.entity.request;

import com.wgzx.modbus.entity.ModbusReq;
import io.netty.buffer.ByteBuf;

import java.util.BitSet;

import static com.wgzx.modbus.constant.FunctionCode.WRITE_MULTIPLE_COILS;
import static com.wgzx.modbus.util.ModbusUtil.validateRange;

/**
 * 写多个线圈 <br/>
 * 功能码：0x0F <br/>
 * 起始地址：2个字节0x0000至0xFFFF <br/>
 * 输出数量：2个字节0x0001至0x07B0 <br/>
 * 字节数：1个字节 <br/>
 * 输出值：N个字节 <br/>
 *
 * @author gexin
 */
public class WriteMultipleCoilsRequest extends ModbusReq {

    private short byteCount;
    private byte[] outputsValue;

    public WriteMultipleCoilsRequest(int startingAddress, int quantityOfOutputs, BitSet outBitSet) {
        super(WRITE_MULTIPLE_COILS, startingAddress, quantityOfOutputs);
        validateRange(startingAddress, "startingAddress", 0x0000, 0xFFFF);
        validateRange(quantityOfOutputs, "quantityOfOutputs", 0x01, 0x07B0);

        //N＝输出数量/8，如果余数不等于 0，那么N = N+1。
        this.byteCount = (short) (quantityOfOutputs % 8 == 0 ? (quantityOfOutputs / 8) : (quantityOfOutputs / 8 + 1));
        this.outputsValue = new byte[byteCount];

        byte[] coils = outBitSet.toByteArray();
        System.arraycopy(coils, 0, outputsValue, 0, coils.length);
    }

    @Override
    public int calculateLength() {
        //父类长度 + byteCount(1个字节) + 数据(N个字节)
        return super.calculateLength() + 1 + byteCount;
    }

    @Override
    public void encode(ByteBuf buffer) {
        super.encode(buffer);
        //byteCount(1个字节)
        buffer.writeByte(byteCount);
        //数据(N个字节)
        buffer.writeBytes(outputsValue);
    }

    @Override
    public String toString() {
        return "WriteMultipleCoilsRequest{" + "startingAddress=" + address + ", quantityOfOutputs=" + value + ", byteCount=" + byteCount + ", outputsValue=" + outputsValue + '}';
    }
}
